package com.bookrecomm.entity;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import javax.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * 图书实体类
 * 对应数据库中的图书表
 */
@Entity
@Table(name = "books")
@Getter
@Setter
@ToString
public class Book {

    /**
     * 图书ID，主键，自增
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 图书名称
     */
    @Column(nullable = false, length = 200)
    private String title;

    /**
     * 图书ISBN编号
     */
    @Column(length = 20)
    private String isbn;

    /**
     * 图书作者
     */
    @Column(length = 100)
    private String author;

    /**
     * 图书出版社
     */
    @Column(name = "publisher", length = 100)
    private String publisher;

    /**
     * 出版日期
     */
    @Column(name = "publish_date")
    private LocalDateTime publishDate;

    /**
     * 图书语言
     */
    @Column(length = 20)
    private String language;

    /**
     * 图书价格
     */
    @Column(precision = 10, scale = 2)
    private BigDecimal price;

    /**
     * 图书页数
     */
    private Integer pages;

    /**
     * 图书封面URL
     */
    @Column(name = "cover_url")
    private String coverUrl;

    /**
     * 图书简介
     */
    @Column(columnDefinition = "TEXT")
    private String description;

    /**
     * 图书目录
     */
    @Column(columnDefinition = "TEXT")
    private String catalog;

    /**
     * 图书评分，平均分
     */
    @Column(precision = 3, scale = 1)
    private BigDecimal rating = BigDecimal.ZERO;

    /**
     * 评分人数
     */
    @Column(name = "rating_count")
    private Integer ratingCount = 0;

    /**
     * 收藏数量
     */
    @Column(name = "favorite_count")
    private Integer favoriteCount = 0;
    
    /**
     * 评论数量
     */
    @Column(name = "comment_count")
    private Long commentCount = 0L;
    
    /**
     * 阅读数量
     */
    @Column(name = "read_count")
    private Long readCount = 0L;
    
    /**
     * 完成阅读数量
     */
    @Column(name = "finish_count")
    private Long finishCount = 0L;
    
    /**
     * 获取图书阅读数量
     * @return 阅读数量
     */
    public Long getReadCount() {
        return readCount != null ? readCount : 0L;
    }
    
    /**
     * 设置图书阅读数量
     * @param readCount 阅读数量
     */
    public void setReadCount(long readCount) {
        this.readCount = readCount;
    }
    
    /**
     * 获取图书完成阅读数量
     * @return 完成阅读数量
     */
    public Long getFinishCount() {
        return finishCount != null ? finishCount : 0L;
    }
    
    /**
     * 设置图书完成阅读数量
     * @param finishCount 完成阅读数量
     */
    public void setFinishCount(long finishCount) {
        this.finishCount = finishCount;
    }

    /**
     * 销售量
     */
    private Integer sales = 0;

    /**
     * 库存量
     */
    private Integer stock = 0;

    /**
     * 图书状态：0-下架，1-上架
     */
    private Integer status = 1;

    /**
     * 图书分类，多对多关系
     */
    @ManyToMany
    @JoinTable(
        name = "book_categories",
        joinColumns = @JoinColumn(name = "book_id"),
        inverseJoinColumns = @JoinColumn(name = "category_id")
    )
    @ToString.Exclude // 确保不在toString中包含categories
    private Set<Category> categories = new HashSet<>();

    /**
     * 图书标签，多对多关系
     */
    @ManyToMany
    @JoinTable(
        name = "book_tags",
        joinColumns = @JoinColumn(name = "book_id"),
        inverseJoinColumns = @JoinColumn(name = "tag_id")
    )
    @ToString.Exclude // 排除避免循环引用
    private Set<Tag> tags = new HashSet<>();

    /**
     * 图书评论，一对多关系
     */
    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)
    @ToString.Exclude // 排除避免循环引用
    private Set<Comment> comments = new HashSet<>();

    /**
     * 阅读历史，一对多关系
     */
    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)
    @ToString.Exclude // 排除避免循环引用
    private Set<ReadHistory> readHistories = new HashSet<>();

    /**
     * 收藏记录，一对多关系
     */
    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)
    @ToString.Exclude // 排除避免循环引用
    private Set<Favorite> favorites = new HashSet<>();

    /**
     * 创建时间
     */
    @CreationTimestamp
    @Column(name = "created_at", updatable = false)
    private LocalDateTime createdAt;

    /**
     * 更新时间
     */
    @UpdateTimestamp
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;
    
    /**
     * 重写equals方法，只比较ID和title等基本属性
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Book book = (Book) o;
        return Objects.equals(id, book.id) && 
               Objects.equals(title, book.title);
    }

    /**
     * 重写hashCode方法，只使用ID和title等基本属性
     */
    @Override
    public int hashCode() {
        return Objects.hash(id, title);
    }
}
